package crayon.ui;
import crayon.fc.*;
import java.awt.event.*;

import java.awt.event.MouseWheelListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import javax.swing.event.MouseInputAdapter;
import java.awt.Point;

public class Interaction  extends MouseInputAdapter implements MouseWheelListener,KeyListener{ 
    private Grapher m_grapher;
    private GestionnaireTracing m_gestionnaireTracing;
  
    enum State {
	OUT{
	    State click(MouseEvent e){
		if(!gestionnaireTracing.onPoint(e.getPoint()))
		    gestionnaireTracing.addPoint(e.getPoint());
		if(gestionnaireTracing.onTan(e.getPoint())){
		    gestionnaireTracing.setPointTan(e.getPoint());
		    return DEFINECONTROLPOINT;
		}
		if(gestionnaireTracing.onPoint(e.getPoint()))
		    gestionnaireTracing.setPoint(e.getPoint());
		return ONPOINT;
	    }

	    State move(MouseEvent e){
		if (!gestionnaireTracing.onPoint(e.getPoint())){
		    gestionnaireTracing.addPoint(e.getPoint());
		    return DEFINECONTROLPOINT;
		}
		return OUT;
	    }	
	    State keypressed(KeyEvent e){
		System.out.println(KeyEvent.getKeyText(e.getKeyCode()));
		return OUT;}
	State keyreleased(KeyEvent e){System.out.println(KeyEvent.getKeyText(e.getKeyCode()));
		return OUT;}

	


	},ONPOINT{
	    State click(MouseEvent e) {
		if(gestionnaireTracing.samePoint(e.getPoint())) return ONPOINT;
		else if(gestionnaireTracing.onPoint(e.getPoint())){
		    gestionnaireTracing.setPoint(e.getPoint());
		    return ONPOINT;
		}
	
	
		gestionnaireTracing.addPoint(e.getPoint());
		return ONPOINT;
	    }
	    State move(MouseEvent e){
		System.out.println(e.getButton());		
		if(gestionnaireTracing.samePoint(e.getPoint())){
		    grapher.tangeante();
		    return DEFINECONTROLPOINT;
		}
		else if (!gestionnaireTracing.onPoint(e.getPoint())){
		    gestionnaireTracing.addPoint(e.getPoint());
		    return DEFINECONTROLPOINT;
		}
		else
		    return ONPOINT;
	    }
	    State press(MouseEvent e){
		if(gestionnaireTracing.onTan(e.getPoint())){
		    gestionnaireTracing.setPointTan(e.getPoint());
		    return DEFINECONTROLPOINT;
		}
		return ONPOINT;
	    }
	    State release(MouseEvent e) {
		if(gestionnaireTracing.samePoint(e.getPoint())) return ONPOINT;
		else if(gestionnaireTracing.onPoint(e.getPoint())){
		    gestionnaireTracing.setPoint(e.getPoint());
		    return ONPOINT;
		}
		gestionnaireTracing.addPoint(e.getPoint());
		return ONPOINT;
	    }	   
	    State keyrelease(KeyEvent e){
		
return ONPOINT;}
	    State keypressed(KeyEvent e){ 
		//ici on passe dans l'etat fin de chemin (CLOSEPATH)
		if(e.getKeyCode()==KeyEvent.VK_SHIFT){
		    grapher.setCrossCursor();
		    return CLOSEPATH;
		}
		if (e.getKeyCode()==KeyEvent.VK_ESCAPE){
		    return NEWPATH;
		    
	
		}
		if (e.getKeyCode()==KeyEvent.VK_DELETE){
		    gestionnaireTracing.delete();
		    return OUT;
		}
		
		if (e.getKeyCode()==KeyEvent.VK_CONTROL)
		    return MOVEPOINT;
		return ONPOINT;
	    }
	    
	    
	},DEFINECONTROLPOINT{
	      State move(MouseEvent e) { 
		  gestionnaireTracing.modifyCtrl(e.getPoint());
		  return DEFINECONTROLPOINT;}
	      State click(MouseEvent e){return DEFINECONTROLPOINT;} 
	      State press(MouseEvent e){return DEFINECONTROLPOINT;}	    
	      State release(MouseEvent e){
		  grapher.tangeante();
		  return ONPOINT;}
	      State keyreleased(KeyEvent e){return DEFINECONTROLPOINT;}
	      State keypressed(KeyEvent e){
		  return DEFINECONTROLPOINT;
	      }
	      
	},MOVEPOINT{
	    State move(MouseEvent e) {
		grapher.setMoveCursor();
		gestionnaireTracing.modify(e.getPoint());
		return MOVEPOINT;}
	    State click(MouseEvent e){return MOVEPOINT;} 
	    State press(MouseEvent e){return MOVEPOINT;}	    
	    State release(MouseEvent e){grapher.backtoNormalcursor();
		return MOVEPOINT;}
	    State keyreleased(KeyEvent e){
		grapher.backtoNormalcursor();
		return ONPOINT;}
	    State keypressed(KeyEvent e){return MOVEPOINT;}
		

	},CLOSEPATH{
	    State move(MouseEvent e) {return CLOSEPATH;}
	    State click(MouseEvent e){
		if(gestionnaireTracing.onPointOfcurrentPath(e.getPoint()))
		    {gestionnaireTracing.setCloserPATH(e.getPoint());}
		return CLOSEPATH;} 
	    State press(MouseEvent e){return CLOSEPATH;}	    
	    State release(MouseEvent e){return CLOSEPATH;}
	    State keyreleased(KeyEvent e){
		if(e.getKeyCode()==KeyEvent.VK_SHIFT){
		    grapher.backtoNormalcursor();
		    return ONPOINT;}
		else 
		    return CLOSEPATH;
	    }
	    State keypressed(KeyEvent e){return CLOSEPATH;}
	    
	},NEWPATH{	
	    State press(MouseEvent e){return NEWPATH;} 
	    State move(MouseEvent e){return NEWPATH;}
	    State release(MouseEvent e) {return NEWPATH;}
	    State click(MouseEvent e){
		if(!gestionnaireTracing.onPoint(e.getPoint())){
		    gestionnaireTracing.NewTracing();
		    gestionnaireTracing.addPoint(e.getPoint());
		    return ONPOINT;}
		if(gestionnaireTracing.onPoint(e.getPoint()))
		    gestionnaireTracing.setPoint(e.getPoint());
		return ONPOINT;
	    }
	    State keypressed(KeyEvent e){return NEWPATH;}
	    State keyreleased(KeyEvent e){return NEWPATH;}
	    


	};
	static Grapher grapher;
	static GestionnaireTracing gestionnaireTracing;
	void _init(GestionnaireTracing g,Grapher gr){grapher=gr;gestionnaireTracing=g;}
	State press(MouseEvent e){return OUT;} 
	State move(MouseEvent e){return OUT;}
	State release(MouseEvent e) {return OUT;}
	State click(MouseEvent e) {return OUT;}
	State keypressed(KeyEvent e){return OUT;}
	State keyreleased(KeyEvent e){return OUT;}

    }
    
    private State state;
    
    
    public Interaction(Grapher grapher,GestionnaireTracing gestionnairetracing) {
	state=State.OUT;
	m_gestionnaireTracing=gestionnairetracing;
	m_grapher=grapher;
	state._init(m_gestionnaireTracing,grapher);
    }
    
    public void mouseClicked(MouseEvent e){
	state = state.click(e); m_grapher.update();
    }
    public void mousePressed(MouseEvent e){	
	state = state.press(e); m_grapher.update();
    }

    public void mouseReleased(MouseEvent e){
	state = state.release(e); m_grapher.update();
    }
    public void mouseDragged(MouseEvent e){
	state = state.move(e); m_grapher.update();
    }
    
    public void mouseWheelMoved(MouseWheelEvent e) {
	m_grapher.update();
    }
    
    
    public void keyTyped(KeyEvent e){
      
    }
    public void	keyPressed(KeyEvent e){
	state = state.keypressed(e); m_grapher.update();
    }
    public void	keyReleased(KeyEvent e){
    	state = state.keyreleased(e); m_grapher.update();
    }

  
}
